"""分镜预览视图模块"""
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
                             QPushButton, QScrollArea, QFrame, QGridLayout,
                             QSpinBox, QComboBox, QMessageBox, QDialog, QSlider)
from PyQt6.QtCore import Qt, pyqtSignal, QSize, QUrl
from PyQt6.QtGui import QPixmap, QImage
from src.ui.styles import (BUTTON_STYLE, INPUT_STYLE, LABEL_STYLE,
                      SCROLL_BAR_STYLE, PROGRESS_BAR_STYLE, MESSAGEBOX_STYLE)
from src.video_processor import SceneInfo
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from PyQt6.QtMultimediaWidgets import QVideoWidget
import tempfile
import os

class VideoPreviewDialog(QDialog):
    """视频预览对话框"""
    
    def __init__(self, video_path, parent=None):
        super().__init__(parent)
        self.setWindowTitle("视频预览")
        self.setMinimumSize(800, 600)
        
        # 创建布局
        layout = QVBoxLayout(self)
        
        # 创建视频播放器
        self.player = QMediaPlayer()
        self.video_widget = QVideoWidget()
        self.player.setVideoOutput(self.video_widget)
        
        # 设置视频源
        self.player.setSource(QUrl.fromLocalFile(video_path))
        
        # 创建控制按钮
        controls_layout = QHBoxLayout()
        
        # 播放/暂停按钮
        self.play_btn = QPushButton("播放")
        self.play_btn.clicked.connect(self._on_play)
        controls_layout.addWidget(self.play_btn)
        
        # 停止按钮
        self.stop_btn = QPushButton("停止")
        self.stop_btn.clicked.connect(self._on_stop)
        controls_layout.addWidget(self.stop_btn)
        
        # 进度条
        self.progress_bar = QSlider(Qt.Orientation.Horizontal)
        self.progress_bar.setRange(0, 0)
        self.progress_bar.sliderMoved.connect(self._on_seek)
        controls_layout.addWidget(self.progress_bar)
        
        # 添加到主布局
        layout.addWidget(self.video_widget)
        layout.addLayout(controls_layout)
        
        # 连接信号
        self.player.durationChanged.connect(self._on_duration_changed)
        self.player.positionChanged.connect(self._on_position_changed)
        self.player.playbackStateChanged.connect(self._on_state_changed)
        self.player.errorOccurred.connect(self._on_error)
        
        # 应用样式
        self._apply_styles()
        
    def _apply_styles(self):
        """应用样式"""
        self.setStyleSheet(f"""
            {BUTTON_STYLE}
            {PROGRESS_BAR_STYLE}
            
            QVideoWidget {{
                background-color: #1e1e2e;
            }}
        """)
        
    def _on_play(self):
        """播放/暂停视频"""
        if self.player.playbackState() == QMediaPlayer.PlaybackState.PlayingState:
            self.player.pause()
        else:
            self.player.play()
            
    def _on_stop(self):
        """停止视频"""
        self.player.stop()
        
    def _on_seek(self, position):
        """跳转到指定位置"""
        self.player.setPosition(position)
        
    def _on_duration_changed(self, duration):
        """视频时长改变"""
        self.progress_bar.setRange(0, duration)
        
    def _on_position_changed(self, position):
        """播放位置改变"""
        self.progress_bar.setValue(position)
        
    def _on_state_changed(self, state):
        """播放状态改变"""
        if state == QMediaPlayer.PlaybackState.PlayingState:
            self.play_btn.setText("暂停")
        else:
            self.play_btn.setText("播放")
            
    def _on_error(self, error, error_string):
        """处理播放器错误"""
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Icon.Critical)
        msg.setWindowTitle("播放错误")
        msg.setText(f"视频播放失败：{error_string}")
        msg.setStyleSheet(MESSAGEBOX_STYLE)
        msg.exec()
        self.close()
            
    def closeEvent(self, event):
        """关闭事件"""
        self.player.stop()
        super().closeEvent(event)

class SceneFrame(QFrame):
    """场景帧组件（无描述，缩略图占位优化）"""
    def __init__(self, scene_data, parent=None):
        super().__init__(parent)
        self.scene_data = scene_data
        self._init_ui()
        self._apply_styles()

    def _init_ui(self):
        main_layout = QHBoxLayout(self)
        main_layout.setContentsMargins(16, 12, 16, 12)
        main_layout.setSpacing(16)

        # 左侧缩略图
        self.preview_label = QLabel()
        self.preview_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.preview_label.setMinimumSize(120, 90)
        self.preview_label.setMaximumSize(120, 90)
        self.preview_label.setStyleSheet("background:#F7F8FA;border:1px solid #EDEDED;border-radius:8px;")
        main_layout.addWidget(self.preview_label)

        # 右侧信息区
        info_layout = QVBoxLayout()
        info_layout.setSpacing(6)
        info_layout.setContentsMargins(0, 0, 0, 0)

        # 顶部：编号、时长、区间
        top_layout = QHBoxLayout()
        top_layout.setSpacing(10)
        top_layout.setContentsMargins(0, 0, 0, 0)
        scene_idx = QLabel(f"场景 {self.scene_data.index}")
        scene_idx.setStyleSheet("font-weight:600;font-size:16px;color:#FF6A00;")
        top_layout.addWidget(scene_idx)
        duration = QLabel(f"{self.scene_data.duration:.1f}秒")
        duration.setStyleSheet("color:#666;font-size:14px;")
        top_layout.addWidget(duration)
        start = getattr(self.scene_data, 'start_time', None)
        end = getattr(self.scene_data, 'end_time', None)
        if start is not None and end is not None:
            time_range = QLabel(f"{self._format_time(start)} ~ {self._format_time(end)}")
            time_range.setStyleSheet("color:#999;font-size:13px;")
            top_layout.addWidget(time_range)
        top_layout.addStretch()
        info_layout.addLayout(top_layout)

        # 底部：操作按钮
        btn_layout = QHBoxLayout()
        btn_layout.setSpacing(12)
        btn_layout.setContentsMargins(0, 0, 0, 0)
        self.preview_btn = QPushButton("预览")
        self.preview_btn.clicked.connect(self._on_preview)
        btn_layout.addWidget(self.preview_btn)
        btn_layout.addStretch()
        info_layout.addLayout(btn_layout)

        main_layout.addLayout(info_layout)

    def _format_time(self, seconds):
        m, s = divmod(int(seconds), 60)
        h, m = divmod(m, 60)
        return f"{h:02d}:{m:02d}:{s:02d}"

    def _apply_styles(self):
        """应用新版喜马拉雅风格样式"""
        XM_PRIMARY = "#FF6A00"
        XM_PRIMARY_DARK = "#FF8C1A"
        XM_CARD = "#FFFFFF"
        XM_TEXT = "#222222"
        XM_TEXT_SECONDARY = "#666666"
        XM_DIVIDER = "#EDEDED"
        self.setStyleSheet(f"""
            QFrame {{
                background-color: {XM_CARD};
                border-radius: 14px;
                border: 1.5px solid {XM_DIVIDER};
                box-shadow: 0 2px 12px rgba(255,106,0,0.08);
            }}
            QFrame:hover {{
                box-shadow: 0 4px 24px rgba(255,106,0,0.16);
                border: 1.5px solid {XM_PRIMARY};
            }}
            QLabel {{
                color: {XM_TEXT};
            }}
            QPushButton {{
                background-color: {XM_PRIMARY};
                color: #fff;
                border: none;
                border-radius: 8px;
                padding: 7px 28px;
                font-size: 15px;
                font-weight: 500;
            }}
            QPushButton:hover {{
                background-color: {XM_PRIMARY_DARK};
            }}
        """)

    def set_preview_image(self, image_path):
        if image_path and os.path.exists(image_path):
            pixmap = QPixmap(image_path)
            scaled_pixmap = pixmap.scaled(
                120, 90,
                Qt.AspectRatioMode.KeepAspectRatio,
                Qt.TransformationMode.SmoothTransformation
            )
            self.preview_label.setPixmap(scaled_pixmap)
            self.preview_label.setText("")
        else:
            # 显示占位图和文字
            self.preview_label.setPixmap(QPixmap())
            self.preview_label.setText("暂无缩略图")
            self.preview_label.setStyleSheet("background:#F7F8FA;border:1px solid #EDEDED;border-radius:8px;color:#bbb;font-size:13px;")

    def _on_preview(self):
        # 优先用已导出片段，否则用原视频区间临时导出
        video_path = self.scene_data.preview_path if self.scene_data.preview_path and self.scene_data.preview_path.endswith('.mp4') else None
        # 自动补全scene_data.video_path
        if not getattr(self.scene_data, 'video_path', None):
            main_window = self.window()
            if hasattr(main_window, 'video_path') and main_window.video_path:
                self.scene_data.video_path = main_window.video_path
            else:
                msg = QMessageBox(self)
                msg.setIcon(QMessageBox.Icon.Critical)
                msg.setWindowTitle("错误")
                msg.setText("无法获取原始视频路径，无法导出片段")
                msg.setStyleSheet(MESSAGEBOX_STYLE)
                msg.exec()
                return
        if not video_path or not os.path.exists(video_path):
            from src.video_processor import VideoProcessor
            processor = VideoProcessor()
            processor.load_video(self.scene_data.video_path)
            tmp_dir = tempfile.gettempdir()
            try:
                # 返回值为导出的视频路径列表
                paths = processor.export_scene_videos([self.scene_data], tmp_dir)
                if paths and os.path.exists(paths[0]):
                    video_path = paths[0]
                else:
                    raise Exception("导出视频片段失败")
            except Exception as e:
                msg = QMessageBox(self)
                msg.setIcon(QMessageBox.Icon.Critical)
                msg.setWindowTitle("错误")
                msg.setText(f"无法导出视频片段：{str(e)}")
                msg.setStyleSheet(MESSAGEBOX_STYLE)
                msg.exec()
                return
        if not os.path.exists(video_path):
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Icon.Critical)
            msg.setWindowTitle("错误")
            msg.setText("视频文件不存在")
            msg.setStyleSheet(MESSAGEBOX_STYLE)
            msg.exec()
            return
        dlg = VideoPreviewDialog(video_path, self)
        dlg.show()

class StoryboardView(QWidget):
    """分镜预览视图类"""
    
    # 自定义信号
    scene_selected = pyqtSignal(dict)  # 场景选择信号
    export_requested = pyqtSignal(list)
    back_requested = pyqtSignal()  # 新增返回信号
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("分镜预览")
        self.scenes = []  # 场景数据列表
        self.video_path = None  # 新增：记录原始视频路径
        self._init_ui()
        self._apply_styles()
        
    def _init_ui(self):
        """初始化UI组件"""
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(20, 20, 20, 20)
        main_layout.setSpacing(20)
        # 直接创建场景网格
        self._create_scene_grid(main_layout)
        # 创建底部按钮栏
        self._create_bottom_buttons(main_layout)
        
    def _create_scene_grid(self, parent_layout):
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.scene_container = QWidget()
        self.scene_layout = QVBoxLayout(self.scene_container)
        self.scroll_area.setWidget(self.scene_container)
        parent_layout.addWidget(self.scroll_area)
        
    def _create_bottom_buttons(self, parent_layout):
        """底部左右分栏按钮"""
        button_layout = QHBoxLayout()
        button_layout.setContentsMargins(0, 0, 0, 0)
        button_layout.setSpacing(10)
        # 左下角返回
        self.back_btn = QPushButton("返回")
        self.back_btn.clicked.connect(self.back_requested.emit)
        button_layout.addWidget(self.back_btn)
        button_layout.addStretch()
        # 右下角导出
        self.export_btn = QPushButton("导出分镜")
        self.export_btn.clicked.connect(self._on_export)
        self.export_btn.setEnabled(False)
        button_layout.addWidget(self.export_btn)
        parent_layout.addLayout(button_layout)
        
    def _apply_styles(self):
        XM_PRIMARY = "#FF6A00"
        XM_PRIMARY_DARK = "#FF8C1A"
        XM_CARD = "#FFFFFF"
        XM_TEXT = "#222222"
        XM_TEXT_SECONDARY = "#666666"
        XM_DIVIDER = "#EDEDED"
        self.setStyleSheet(f"""
            QFrame {{
                background-color: {XM_CARD};
                border-radius: 14px;
                border: 1.5px solid {XM_DIVIDER};
                box-shadow: 0 2px 12px rgba(255,106,0,0.08);
            }}
            QFrame:hover {{
                box-shadow: 0 4px 24px rgba(255,106,0,0.16);
                border: 1.5px solid {XM_PRIMARY};
            }}
            QLabel {{
                color: {XM_TEXT};
            }}
            QPushButton {{
                background-color: {XM_PRIMARY};
                color: #fff;
                border: none;
                border-radius: 8px;
                padding: 7px 28px;
                font-size: 15px;
                font-weight: 500;
            }}
            QPushButton:hover {{
                background-color: {XM_PRIMARY_DARK};
            }}
        """)
        
    def set_scenes(self, scenes, video_path=None):
        """设置场景数据并补全video_path"""
        self.video_path = video_path or getattr(self, 'video_path', None)
        # 批量补全每个scene的video_path
        for scene in scenes:
            if not getattr(scene, 'video_path', None):
                scene.video_path = self.video_path
        self.scenes = scenes
        self._update_grid()
        
    def _update_grid(self):
        # 清除现有场景
        while self.scene_layout.count():
            item = self.scene_layout.takeAt(0)
            if item.widget():
                item.widget().deleteLater()
        if not self.scenes:
            return
        # 直接顺序展示所有场景
        for i, scene in enumerate(self.scenes):
            frame = SceneFrame(scene)
            frame.set_preview_image(getattr(scene, 'preview_path', None))
            self.scene_layout.addWidget(frame)
        self.export_btn.setEnabled(True)
        
    def _on_export(self):
        """导出分镜"""
        if not self.scenes:
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Icon.Warning)
            msg.setWindowTitle("警告")
            msg.setText("没有可导出的场景")
            msg.setStyleSheet(MESSAGEBOX_STYLE)
            msg.exec()
            return
        
        # 获取所有场景信息
        scenes = []
        for i in range(self.scene_layout.count()):
            frame = self.scene_layout.itemAt(i).widget()
            if frame and hasattr(frame, 'scene_data'):
                scenes.append(frame.scene_data)
        self.export_requested.emit(scenes) 